package com.ttg.utils;
//~--- non-JDK imports --------------------------------------------------------
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.TreeMap;
import com.ttg.utilspaidui.Constant;
import net.sf.json.JSONObject;
//~--- JDK imports ------------------------------------------------------------
//~--- classes ----------------------------------------------------------------
/**
 Class TLinx2Util
 Description
 Create 2017-03-07 14:01:23
 @author Benny.YEE */
public class TLinx2Util{
    /**
     签名
     @param postMap
     @return
     */
    public static String sign(Map<String,String> postMap){
        String sortStr = null;
        String sign = null;
        try{
            /**
             * 1 A~z排序(加上open_key)
             */
            sortStr = TLinxUtil.sort(postMap);
            /**
             * 2 sha1加密(小写)
             */
            String sha1 = TLinxSHA1.SHA1(sortStr);
            /**
             * 3 md5加密(小写)
             */
            sign = MD5.MD5Encode(sha1).toLowerCase();
        } catch(Exception e){
            e.printStackTrace();
        }
        return sign;
    }
    public static String signRSA(Map<String,String> postMap){
        String sortStr = null;
        String sign = null;
        try{
            /**
             * 1 A~z排序(加上open_key)
             */
            sortStr = TLinxUtil.sort(postMap);
            sign = TLinxRSACoder.sign(sortStr.getBytes("utf-8"),TestParams.PRIVATE_KEY);
        } catch(Exception e){
            e.printStackTrace();
        }
        return sign;
    }
    /**
     signRSA with key
     */
    public static String signRSA(Map<String,String> postMap,String privateKey){
        String sortStr = null;
        String sign = null;
        try{
            /**
             * 1 A~z排序(加上open_key)
             */
            sortStr = TLinxUtil.sort(postMap);
            sign = TLinxRSACoder.sign(sortStr.getBytes("utf-8"),privateKey);
        } catch(Exception e){
            e.printStackTrace();
        }
        return sign;
    }
    /**
     验签
     @param respObject
     @return
     */
    public static Boolean verifySign(JSONObject respObject){
        String respSign = respObject.get("sign").toString();
        // 删除sign节点
        respObject.remove("sign");
        //respObject.put("open_key",TestParams.OPEN_KEY);
        // 按A~z排序，串联成字符串，先进行sha1加密(小写)，再进行md5加密(小写)，得到签名
        String veriSign = sign(respObject);
        if(respSign.equals(veriSign)){
            System.out.println("=====验签成功=====");
            return true;
        } else{
            System.out.println("=====验签失败=====");
        }
        return false;
    }
    /**
     AES加密，再二进制转十六进制(bin2hex)
     @param postmap 说明：
     @exception Exception
     */
    public static void handleEncrypt(TreeMap<String,String> datamap,TreeMap<String,String> postmap) throws Exception{
        JSONObject dataobj = JSONObject.fromObject(datamap);
        String data = TLinxAESCoder.encrypt(dataobj.toString(),TestParams.OPEN_KEY);    // AES加密，并bin2hex
        postmap.put("data",data);
    }
    /**
     签名
     @param postmap
     */
    public static void handleSign(TreeMap<String,String> postmap){
        Map<String,String> veriDataMap = new HashMap<String,String>();
        veriDataMap.putAll(postmap);
        veriDataMap.put("open_key",TestParams.OPEN_KEY);
        // 签名
        String sign = sign(veriDataMap);
        postmap.put("sign",sign);
    }
    /**
     签名
     @param postmap
     */
    public static void handleSignRSA(TreeMap<String,String> postmap){
        Map<String,String> veriDataMap = new HashMap<String,String>();
        veriDataMap.putAll(postmap);
        veriDataMap.put("open_key",TestParams.OPEN_KEY);
        // 签名
        String sign = signRSA(veriDataMap);
        postmap.put("sign",sign);
    }
    /**
     请求接口
     @param postmap
     @return 响应字符串
     */
    public static String handlePost(TreeMap<String,String> postmap,String interfaceName){
        String url = TestParams.OPEN_URL + interfaceName;
        if(url.contains("https")){
            return HttpsUtil.httpMethodPost(url,postmap,"UTF-8");
        } else{
            return HttpUtil.httpMethodPost(url,postmap,"UTF-8");
        }
    }
    /**
     请求接口
     @param postmap
     @return 响应字符串
     */
    public static String handlePostPaiDui(TreeMap<String,String> postmap,String interfaceName){
        //String url = Constant.OPEN_URL+interfaceName;
        String url = Constant.TESTOPEN_URL+interfaceName;
        if(url.contains("https")){
            return HttpsUtil.httpMethodPost(url,postmap,"UTF-8");
        } else{
            return HttpUtil.httpMethodPost(url,postmap,"UTF-8");
        }
    }
    
    public static String getNonceStr(){
        Random random = new Random();
        return MD5Util.MD5Encode(String.valueOf(random.nextInt(10000)),"UTF-8");
    }
    
    public static void doJsonPost(String urlStr, TreeMap<String, String> map) {
        try {
            URL url = new URL(urlStr);
            
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            
            connection.setRequestMethod("POST");
            connection.setDoInput(true);
            connection.setDoOutput(true);
            connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
            connection.setRequestProperty("Accept", "application/json");
            
            String postData = JSONObject.fromObject(map).toString();
            connection.connect();
            OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
            writer.write(postData);
            writer.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     Method main
     Description 说明：
     @param args 说明：
     */
    public static void main(String[] args){
        // 初始化参数
        String pmtType = "0,1,2,3";
        //String timestamp = new Date().getTime() / 1000 + "";    // 时间
        String timestamp = System.currentTimeMillis() / 1000 + "";    // 时间
        try{
            // 固定参数
            TreeMap<String,String> postmap = new TreeMap<String,String>();//请求参数的map
            postmap.put("open_id",TestParams.OPEN_ID);
            postmap.put("timestamp",timestamp);
            TreeMap<String,String> datamap = new TreeMap<String,String>();//data参数的map
            datamap.put("pmt_type",pmtType);
            /**
             * 1 data字段内容进行AES加密，再二进制转十六进制(bin2hex)
             */
            handleEncrypt(datamap,postmap);
            /**
             * 2 请求参数签名 按A~z排序，串联成字符串，先进行sha1加密(小写)，再进行md5加密(小写)，得到签名
             */
            handleSign(postmap);
            /**
             * 3 请求、响应
             */
            String rspStr = handlePost(postmap,TestParams.PAYLIST);
            /**
             * 4 验签  有data节点时才验签
             */
            JSONObject respObject = JSONObject.fromObject(rspStr);
            Object dataStr = respObject.get("data");
            System.out.println("返回data字符串=" + dataStr);
            if(!rspStr.isEmpty() || (dataStr != null)){
                if(verifySign(respObject)){    // 验签成功
                    /**
                     * 5 AES解密，并hex2bin
                     */
                    String respData = TLinxAESCoder.decrypt(dataStr.toString(),TestParams.OPEN_KEY);
                    System.out.println("==================响应data内容:" + respData);
                } else{
                    System.out.println("=====验签失败=====");
                }
            } else{
                System.out.println("=====没有返回data数据=====");
            }
        } catch(Exception e){
            e.printStackTrace();
        }
    }
}
//~ Formatted by Jindent --- http://www.jindent.com
